package com.free.bsf.sentinel;

import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import com.free.bsf.core.common.PropertyCache;
import com.free.bsf.core.config.BsfConfiguration;
import com.free.bsf.core.config.CoreProperties;
import com.free.bsf.core.util.LogUtils;
import com.free.bsf.core.util.PropertyUtils;
import com.free.bsf.core.util.StringUtils;
import com.free.bsf.core.util.WebUtils;
import lombok.val;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.util.ArrayList;
import java.util.List;

@Configuration
@ConditionalOnProperty(name = "bsf.sentinel.enabled", havingValue = "true")
@Import(BsfConfiguration.class)
@EnableConfigurationProperties({SentinelProperties.class})
public class SentinelConfiguration implements InitializingBean {
    @ConditionalOnProperty(name = "bsf.sentinel.web.enabled", havingValue = "true", matchIfMissing = true)
    @Bean
    @ConditionalOnWebApplication
    public FilterRegistrationBean sentinelFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        // 优先注入
        filterRegistrationBean.setOrder(0);
        filterRegistrationBean.setFilter(new SentinelFilter());
        filterRegistrationBean.setName("sentinelFilter");
        filterRegistrationBean.addUrlPatterns("/*");
        LogUtils.info(SentinelConfiguration.class, SentinelProperties.Project,
                "sentinelFilter web限流注册成功");
        return filterRegistrationBean;
    }

    @Bean
    @ConditionalOnProperty(name ="bsf.sentinel.feign.enabled", havingValue = "true", matchIfMissing = true)
    @ConditionalOnClass(name = "org.aspectj.lang.annotation.Aspect")
    public FeignClientSentinelAspect feignClientSentinelAspect(){
        return new FeignClientSentinelAspect();
    }

    @Bean
    @ConditionalOnProperty(name ="bsf.sentinel.resourceAspect.enabled", havingValue = "true", matchIfMissing = true)
    @ConditionalOnClass(name = "org.aspectj.lang.annotation.Aspect")
    public SentinelResourceAspect sentinelResourceAspect(){
        return new SentinelResourceAspect();
    }

    @Override
    public void afterPropertiesSet() {
        SentinelUtils.refreshConfig(new ArrayList<String>(),true);
        initConfigChangeListen();
        LogUtils.info(SentinelConfiguration.class,SentinelProperties.Project,"已启动!!!");
    }

    protected void initConfigChangeListen(){
        PropertyCache.Default.listenUpdateCache("限流配置刷新上下文监听",(data)->{
            if(data!=null&&data.size()>0){
                List<String> configRefresh = new ArrayList<>();
                for(val e:data.entrySet()){
                    if(e.getKey().startsWith(SentinelProperties.BsfSentinel)){
                        configRefresh.add(e.getKey());
                    }
                }
                if(configRefresh.size()>0) {
                    SentinelUtils.refreshConfig(configRefresh,false);
                }
            }
        });
    }


}
